import cv2
import numpy as np
import matplotlib.pyplot as plt

#纵向拼接
#用matplotlib显示图像
def show_Image_Plt(Image, title=None, cmap=None):
    plt.imshow(Image, cmap=cmap)
    plt.title(title)
    plt.axis(False)
    plt.show()
#用Opencv显示图像
def show_Image_Cv(Image, Name="Demo"):
    cv2.namedWindow(Name,cv2.WINDOW_NORMAL)
    cv2.imshow(Name, Image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
#读取图片
def ReadImage(Path):
    Image=cv2.imread(Path)
    Image_Size=cv2.resize(Image,None,fx=0.6,fy=0.6)
    Image_Gray=cv2.cvtColor(Image_Size,cv2.COLOR_BGR2GRAY)
    return Image_Gray
#使用SIFT获取图像特征点
def Sift(Image):
    Sift = cv2.SIFT_create()
    keypoint, describe = Sift.detectAndCompute(Image, None)
    keypoint_xy = np.float32([i.pt for i in keypoint]) #获取Keypoint  xy点位
    Image_draw = cv2.drawKeypoints(Image, keypoint, None, None)   #显示特征点
    # show_Image_Cv(Image_draw)
    return keypoint,describe,keypoint_xy

#融合，对第二张图片进行透视变换，然后将第一张图拼接到第二张图，所以拼接重叠部分为第一部分。
def Mosaic(Image_First, Image_Last,Col):
    KeyPoint_F,Describe_F,KeyPoint_xy_F=Sift(Image_First) #First 第一张图
    KeyPoint_L,Describe_L,KeyPoint_xy_L=Sift(Image_Last)  #Last 第二张图
    matcher = cv2.BFMatcher()
    rawMatcher = matcher.knnMatch(Describe_L, Describe_F, k=2)
    Match = []
    for n, m in rawMatcher:
        if n.distance < m.distance * 0.75:
            Match.append([n.trainIdx, n.queryIdx])

    PtsA = np.float32([KeyPoint_xy_F[i] for (i, _) in Match])     #获取各自匹配上的点坐标，这是第一张
    PtsB = np.float32([KeyPoint_xy_L[i] for (_, i) in Match])

    Mat, _ = cv2.findHomography(PtsB, PtsA, cv2.RANSAC, 4)
    Image_Affine = cv2.warpPerspective(Image_Last, Mat, [384, Col+500])   #要看自己图像像素大小，我的图片缩小后是384*288，+500纯属为了不让第二张图后面部分丢失
    # show_Image_Cv(Image_Affine)
    Image_Affine[0:Image_First.shape[0], 0:Image_First.shape[1]] = Image_First   #拼接
    # show_Image_Cv(Image_Affine, Name='Image_Affine')
    return Image_Affine

#因为无法确定拼接后图像大小（图像重叠部分），而12图拼接后面很多是灰度为0的像素，剔除掉
def Image_Resize(Image_Demo):
    Row=int((np.nonzero(Image_Demo)[0].shape[0])/384)
    # print(Row)
    Image=Image_Demo[0:Row,0:384]
    # print(Image_12.shape)
    # show_Image_Cv(Image_12)
    return Image

Image_1=ReadImage("int_pcb/01.png")
Image_2=ReadImage("int_pcb/02.png")
Image_3=ReadImage("int_pcb/03.png")
Image_4=ReadImage("int_pcb/04.png")
Image_5=ReadImage("int_pcb/05.png")
Image_6=ReadImage("int_pcb/06.png")

#1+2
Image_1_Col=Image_1.shape[0]
Image_12_Demo = Mosaic(Image_1, Image_2,Col=Image_1_Col)
show_Image_Cv(Image_12_Demo)
Image_12=Image_Resize(Image_12_Demo)
show_Image_Cv(Image_12_Demo)

#12 +3
Image_12_Col=Image_12.shape[0]
Image_123_Demo = Mosaic(Image_12, Image_3,Col=Image_12_Col)
show_Image_Cv(Image_123_Demo)
Image_123=Image_Resize(Image_123_Demo)
show_Image_Cv(Image_123)

#123 +4
Image_123_Col=Image_123.shape[0]
Image_1234_Demo = Mosaic(Image_123, Image_4,Col=Image_123_Col)
show_Image_Cv(Image_1234_Demo)
Image_1234=Image_Resize(Image_1234_Demo)
show_Image_Cv(Image_1234)

#1234 +5
Image_12334_Col=Image_1234.shape[0]
Image_12345_Demo = Mosaic(Image_1234, Image_5,Col=Image_12334_Col)
show_Image_Cv(Image_12345_Demo)
Image_12345=Image_Resize(Image_12345_Demo)
show_Image_Cv(Image_12345)

#12345 +6
Image_123345_Col=Image_12345.shape[0]
Image_123456_Demo = Mosaic(Image_12345, Image_6,Col=Image_123345_Col)
show_Image_Cv(Image_123456_Demo)
Image_123456=Image_Resize(Image_123456_Demo)
show_Image_Cv(Image_123456)


